﻿#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Text;
using Newtonsoft.Utilities.Testing;
using NUnit.Framework;
using Newtonsoft.Utilities.Logging;
using System.IO;
using Newtonsoft.Utilities.Text;
using System.Globalization;
using Newtonsoft.Utilities.Locator;
using Newtonsoft.Utilities.Time;

namespace Newtonsoft.Utilities.Tests.Logging
{
  public class TextExceptionFormatterTests : TestsBase
  {
    [Test]
    public void UnthrownException()
    {
      Exception ex = new Exception("Test message.");

      StringWriter sw = new StringWriter();
      ExceptionFormatter formatter = new TextExceptionFormatter(sw, ex);
      formatter.Format();

      string result = sw.ToString();
      string expected =
        @"An exception of type 'System.Exception' occurred and was caught.
----------------------------------------------------------------
{0}
Type : System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Test message.
Source : 
Help link : 
Data : System.Collections.ListDictionaryInternal
TargetSite : 
Stack Trace : The stack trace is unavailable.
Additional Info:

MachineName : {1}
TimeStamp : 1/01/2000 1:01:00 a.m.
FullName : Newtonsoft.Utilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppDomainName : {2}
ThreadIdentity : 
WindowsIdentity : {3}
"
          .FormatWith(CultureInfo.InvariantCulture,
                      ServiceLocator.Clock.UtcDateTime().ToLocalTime().ToString("G", CultureInfo.InvariantCulture),
                      Environment.MachineName,
                      AppDomain.CurrentDomain.FriendlyName,
                      WindowsIdentity.GetCurrent().Name);

      Assert.AreEqual(expected, result.EnsureCarriageReturns());
    }

    [Test]
    public void ThrownException()
    {
      try
      {
        throw new Exception("Test message.");
      }
      catch (Exception ex)
      {
        StringWriter sw = new StringWriter();
        ExceptionFormatter formatter = new TextExceptionFormatter(sw, ex);
        formatter.Format();

        string result = sw.ToString();

        StringAssert.StartsWith(@"An exception of type 'System.Exception' occurred and was caught.
----------------------------------------------------------------
{0}
Type : System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Test message.
Source : Newtonsoft.Utilities.Tests
Help link : 
Data : System.Collections.ListDictionaryInternal
TargetSite : Void ThrownException()
Stack Trace :".FormatWith(CultureInfo.InvariantCulture,
   ServiceLocator.Clock.UtcDateTime().ToLocalTime().ToString("G", CultureInfo.InvariantCulture)), result.EnsureCarriageReturns());
        
        StringAssert.EndsWith(@"Additional Info:

MachineName : {0}
TimeStamp : 1/01/2000 1:01:00 a.m.
FullName : Newtonsoft.Utilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppDomainName : {1}
ThreadIdentity : 
WindowsIdentity : {2}
".FormatWith(CultureInfo.InvariantCulture,
   Environment.MachineName,
   AppDomain.CurrentDomain.FriendlyName,
   WindowsIdentity.GetCurrent().Name), result.EnsureCarriageReturns());
      }
    }

    [Test]
    public void NestedThrownExceptions()
    {
      try
      {
        throw new Exception("Test message.");
      }
      catch (Exception e)
      {
        try
        {
          throw new InvalidOperationException("Outer exception.", e);
        }
        catch (Exception ex)
        {
          StringWriter sw = new StringWriter();
          ExceptionFormatter formatter = new TextExceptionFormatter(sw, ex);
          formatter.Format();

          string result = sw.ToString();

          StringAssert.StartsWith(
            @"An exception of type 'System.InvalidOperationException' occurred and was caught.
--------------------------------------------------------------------------------
{0}
Type : System.InvalidOperationException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Outer exception.
Source : Newtonsoft.Utilities.Tests
Help link : 
Data : System.Collections.ListDictionaryInternal
TargetSite : Void NestedThrownExceptions()
Stack Trace :"
              .FormatWith(CultureInfo.InvariantCulture,
                          ServiceLocator.Clock.UtcDateTime().ToLocalTime().ToString("G", CultureInfo.InvariantCulture)), result.EnsureCarriageReturns());

          StringAssert.Contains(
            @"	Inner Exception
	---------------
	Type : System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
	Message : Test message.
	Source : Newtonsoft.Utilities.Tests
	Help link : 
	Data : System.Collections.ListDictionaryInternal
	TargetSite : Void NestedThrownExceptions()
	Stack Trace :", result);
        }
      }
    }
  }
}